﻿using System;

namespace LightCAD.Core
{
    public struct Box2d
    {
        /// <summary>
        /// 位置,也就是矩形的左下角坐标
        /// </summary>
        public Vector2d Location;

        /// <summary>
        /// 宽、高
        /// </summary>
        public double Width;
        public double Height;

        public Vector2d leftBottom
        {
            get { return Location; }
        }

        public Vector2d leftTop
        {
            get
            {
                return new Vector2d(this.Location.X, this.Location.Y + Height);
            }
        }

        public Vector2d rightTop
        {
            get
            {
                return new Vector2d(this.Location.X + this.Width,
                    this.Location.Y + this.Height);
            }
        }

        public Vector2d rightBottom
        {
            get
            {
                return new Vector2d(this.Location.X + this.Width, this.Location.Y);
            }
        }
        public Vector2d center
        {
            get
            {
                return new Vector2d(this.Location.X + this.Width / 2, this.Location.Y + this.Height / 2);
            }
        }
        public Box2d(Vector2d location, double width, double height)
        {
            this.Location = location;
            this.Width = width;
            this.Height = height;
        }

        public Box2d(Vector2d point1, Vector2d point2)
        {
            double minX = point1.X < point2.X ? point1.X : point2.X;
            double minY = point1.Y < point2.Y ? point1.Y : point2.Y;
            this.Location = new Vector2d(minX, minY);
            this.Width = Math.Abs(point2.X - point1.X);
            this.Height = Math.Abs(point2.Y - point1.Y);
        }
        public bool IntersectWith(Box2d box)
        {
            var boxMax = box.rightTop;
            var thisMax = this.rightTop;
            // using 4 splitting planes to rule out intersections
            return boxMax.X < this.Location.X || box.Location.X > thisMax.X ||
                boxMax.Y < this.Location.Y || box.Location.Y > thisMax.Y ? false : true;

        }
        /// <summary>
        /// Check whether contains point
        /// </summary>
        public bool Contains(Box2d box)
        {
            return this.Contains(box.Location) && this.Contains(box.rightTop);
        }
        /// <summary>
        /// Check whether contains point
        /// </summary>
        public bool Contains(Vector2d point)
        {
            return this.Contains(point.X, point.Y);
        }

        /// <summary>
        /// Check whether contains point: (x, y)
        /// </summary>
        public bool Contains(double x, double y)
        {
            return x >= this.Location.X
                && x <= this.Location.X + this.Width
                && y >= this.Location.Y
                && y <= this.Location.Y + this.Height;
        }
        public override string ToString()
        {
            return string.Format("Rectangle2(({0}, {1}), {2}, {3})",
                this.Location.X,
                this.Location.Y,
                this.Width,
                this.Height);
        }

        public void Union(Box2d box)
        {
            if (this.Width < 0 || this.Height < 0)
            {
                this.Location = box.Location;
                this.Width = box.Width;
                this.Height = box.Height;
            }
            else
            {
                this.Location.X = Math.Min(this.Location.X, box.Location.X);
                this.Location.Y = Math.Min(this.Location.Y, box.Location.Y);
                var trX = Math.Max(this.Location.X+this.Width, box.Location.X+box.Width);
                var trY= Math.Max(this.Location.Y + this.Height, box.Location.Y + box.Height);
                this.Width = trX - this.Location.X;
                this.Height = trY - this.Location.Y;
            }

        }

        public void SetEmpty()
        {
            this.Location = new Vector2d();
            this.Width = -1;
            this.Height = -1;
        }
    }
}
